package site.syksy.qingzhou.security.authorization;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import site.syksy.qingzhou.security.domain.GeneralLoginVO;
import site.syksy.qingzhou.upms.domain.RouteDO;
import site.syksy.qingzhou.upms.service.CommonService;
import site.syksy.qingzhou.upms.service.RouteService;

import java.util.Collection;
import java.util.List;

/**
 * @author Raspberry
 */
@Component
public class GeneralAccessDecisionVoter implements AccessDecisionVoter<FilterInvocation> {

    private final static String ANONYMOUS_USER = "anonymousUser";

    @Autowired
    CommonService commonService;

    @Autowired
    RouteService routeService;

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }

    @Override
    public int vote(Authentication authentication, FilterInvocation filterInvocation, Collection<ConfigAttribute> attributes) {
        AntPathMatcher matcher = new AntPathMatcher();

        String url = filterInvocation.getRequest().getRequestURI();
        String requestMethod = filterInvocation.getRequest().getMethod();

        /**
         * 免登录
         */
        List<RouteDO> noLoginRouteList = routeService.selectByNoLogin();
        for (RouteDO routeDO : noLoginRouteList) {
            String rm = routeDO.getRequestMethod();
            if ("*".equals(rm) || requestMethod.equals(rm)) {
                if (matcher.match(routeDO.getPattern(), url)) {
                    return ACCESS_GRANTED;
                }
            }
        }

        /**
         * 已登录
         */
        Object principal = authentication.getPrincipal();
        if (!ANONYMOUS_USER.equals(principal)) {
            List<RouteDO> loginRouteList = routeService.selectByLogin();
            for (RouteDO routeDO : loginRouteList) {
                String rm = routeDO.getRequestMethod();
                if ("*".equals(rm) || requestMethod.equals(rm)) {
                    if (matcher.match(routeDO.getPattern(), url)) {
                        return ACCESS_GRANTED;
                    }
                }
            }
        }else{
            return CollectionUtils.isEmpty(attributes) ? ACCESS_GRANTED : ACCESS_DENIED;
        }

        /**
         * 授权
         */
        GeneralLoginVO generalLoginVO = (GeneralLoginVO) authentication.getCredentials();
        List<RouteDO> routeDOList = commonService.selectRouteByUserId(generalLoginVO.getUserId(), requestMethod);
        if(routeDOList!=null && routeDOList.size()>0){
            for (RouteDO routeDO : routeDOList) {
                if (matcher.match(routeDO.getPattern(), url)) {
                    return ACCESS_GRANTED;
                }
            }
        }


        return ACCESS_DENIED;
        //return ACCESS_GRANTED;
    }
}
